#ifndef __ram_manager__
#define __ram_manager__

#include <stdint.h>

enum rmb_flags
{
	rbf_valid	= 1,
	rbf_swap	= 2,
	rbf_lock	= 4,
	rbf_fixpma	= 8,
};

typedef uint64_t	pma_t;
typedef size_t		swap_id_t;

struct rmb_t;

struct i_ram_owner_t
{
	virtual void on_ram_block_invalid( rmb_t * pref ) = 0;
};

struct rmb_t
{
	i_ram_owner_t *	owner;	//4	8
	pma_t			pmaf;	//8	
	swap_id_t		pfidx;	//4 8
	pma_t pma( ) { return pmaf & ~0xFFF; };
	size_t flags() { return pmaf & 0xFFF; };
};

//
//	in windows, i suggest using file mapping instead of malloc/VirtuaAlloc, if i DO NOT use KernelMode VCPU(VT)
//

long			rmm_init( size_t block_size, size_t blocks, const char * swapfile_name );
long			rmm_destroy();
void *			rmm_get_base();
size_t			rmm_get_size();
size_t			rmb_size();

long			rmb_alloc( rmb_t * pref, uint32_t flags );
long			rmb_free( rmb_t * pref );
long			rmb_invalid( rmb_t * pref );
long			rmb_swap_out( rmb_t * pref, bool force );
long			rmb_swap_in( rmb_t * pref );
long			rmb_direct_get( rmb_t * pref, void** pp, void * p );
long			rmb_direct_write( rmb_t * pref, size_t off, const void* pbuf, size_t bytes );
long			rmb_direct_read( rmb_t * pref, size_t off, void* pbuf, size_t bytes );
void *			rmb_hptr( rmb_t * pref, bool force = true );
void *			rmb_hptr2( pma_t pma );
size_t			rmb_pma( rmb_t * pref );
long			rmb_enusre( rmb_t * pref );
void*			rmb_lock( rmb_t * pref );
long			rmb_unlock( rmb_t * pref );

static long		rmb_init( rmb_t * pref ) { pref->pmaf = 0; pref->owner = 0; pref->pfidx = 0; return 0;};
static long		rmb_valid( rmb_t * pref ) { if( !pref ) return 0; return pref->pmaf & rbf_valid; };
static long		rmb_swapped( rmb_t * pref ) { return pref->pmaf & rbf_swap; };
#endif